<?php
/**
 * 验证码生成类
 * @author Bun <bunwong@qq.com>
 */
class CaptchaModel extends BpfModel
{
  private static $_string = '1234567890';

  /**
   * 生成验证码
   * @param string $key 验证码标识
   * @param int $len 验证码长度
   * @return string
   */
  public function buildCode($key, $len = 4)
  {
    if (!isset($_SESSION['captcha'])) {
      $_SESSION['captcha'] = array();
    }
    $length = strlen(self::$_string) - 1;
    $code = '';
    for ($i = 0; $i < $len; ++$i) {
      $code .= self::$_string[mt_rand(0, $length)];
    }
    $_SESSION['captcha'][$key] = array(
      'code' => $code,
      'expires' => REQUEST_TIME + 300,  // 5 分钟失效
    );
    return $code;
  }

  /**
   * 检查验证码是否正确
   * @param string $key 验证码标识
   * @param string $code 验证码
   * @return bool
   */
  public function checkCode($key, $code)
  {
    $result = isset($_SESSION['captcha']) && isset($_SESSION['captcha'][$key]) &&
        0 == strcasecmp($_SESSION['captcha'][$key]['code'], $code) &&
        REQUEST_TIME <= $_SESSION['captcha'][$key]['expires'];
    $_SESSION['captcha'][$key] = null;
    return $result;
  }

  /**
   * 输出验证码
   * @param string $key 验证码标识
   */
  public function display($key, $weight, $height, $isjson = false)
  {
    if (!isset($_SESSION['captcha']) || !isset($_SESSION['captcha'][$key])) {
      return false;
    }
    $weight = min(max(intval($weight), 30), 600);
    $height = min(max(intval($height), 30), 600);
    $im = imagecreatetruecolor($weight, $height);
    $this->_drawBackground($im);
    $fontfile = dirname(__FILE__) . '/captcha_fonts/' . sprintf('%02d', mt_rand(1, 4)) . '.ttf';
    $code = $_SESSION['captcha'][$key]['code'];
    $len = strlen($code);
    $size = mt_rand(25, 30);
    for ($i = 0; $i < $len; ++$i) {
      $color = imagecolorallocate($im, mt_rand(0x00, 0x55), mt_rand(0x00, 0x55), mt_rand(0x00, 0x55));
      imagettftext($im, $size, mt_rand(-30, 30), 30 + 30 * $i + mt_rand(-5, 5), mt_rand(30, 35),
          $color, $fontfile, $code[$i]);
    }
    if ($isjson) {
      ob_start();
      imagepng($im);
      $imagedata = ob_get_contents();
      ob_end_clean();
      return 'data:image/png;base64,' . base64_encode($imagedata);
    }
    header('Content-type: image/png');
    imagepng($im);
    imagedestroy($im);
  }

  public function qrcode($text, $logoUrl = '', $color = '')
  {
    BpfCore::loadLibrary('qrcode');
    $errorCorrectionLevel = 'L';//容错级别
    $matrixPointSize = 15;//生成图片大小
    $rs = randomString(8) . REQUEST_TIME;
    $QRPath = VARPATH . '/base_' . $rs . '.png'; // 自定义生成的。结束后可以删除
    $last = VARPATH . '/last_' . $rs . '.png'; // 最终生成的图片
    $QR = $QRPath;
    QRcode::png($text, $QR, $errorCorrectionLevel, $matrixPointSize, false, null, $color);
    //生成二维码图片
    if (!empty($logoUrl)) {
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL, $logoUrl);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_HEADER, 0);
      $logo = curl_exec($ch);
      curl_close($ch);
      $QR = imagecreatefromstring(file_get_contents($QR));
      $logo = imagecreatefromstring($logo);
      $QR_width = imagesx($QR);
      $QR_height = imagesy($QR);
      $logo_width = imagesx ( $logo );
      $logo_height = imagesy ( $logo );
      $logo_qr_width = $QR_width / 5;
      $scale = $logo_width / $logo_qr_width;
      $logo_qr_height = $logo_height / $scale;
      $from_width = ($QR_width - $logo_qr_width) / 2;
      imagecopyresampled ( $QR, $logo, $from_width, $from_width, 0, 0, $logo_qr_width, $logo_qr_height, $logo_width, $logo_height );
      imagepng($QR, $last);
      $result = base64_encode(file_get_contents($last));
      unlink($last);
    } else {
      $result = base64_encode(file_get_contents($QR));
    }
    unlink($QRPath);
    return $result;
  }

  private function _drawBackground($im)
  {
    $w = imagesx($im);
    $h = imagesy($im);
    imagefill($im, 0, 0, imagecolorallocate($im, 0xff, 0xff, 0xff));
    for($i = 0; $i < 8; ++$i){
      $noiseColor = imagecolorallocate($im, mt_rand(0xaa, 0xee), mt_rand(0xaa, 0xee), mt_rand(0xaa, 0xee));
      for($j = 0; $j < 5; ++$j) {
        imagestring($im, mt_rand(2, 5), mt_rand(-10, $w), mt_rand(-10, $h), randomString(1), $noiseColor);
      }
    }
  }
}
